import React, { useState, useEffect } from 'react';
import { Menu, Modal, Tabs, Layout, ConfigProvider, message, Select, Form } from 'antd';
import { ExclamationCircleOutlined } from '@ant-design/icons';

const { Header, Sider, Content } = Layout;
const { SubMenu } = Menu;
const { TabPane } = Tabs;
import { connect } from 'umi';
import { isUrl } from '@/utils/utils';
import MyHeader from '@/components/Layout/Header';
import MyFooter from '@/components/Layout/Footer';
import HomePage from '@/pages/homePage/index';
import Error403 from '@/pages/403';
import Error404 from '@/pages/404';
import SysName from '@/components/Layout/SysName';
import zhCN from 'antd/lib/locale/zh_CN';
import './index.less';
import { ModalForm, ProFormText } from '@ant-design/pro-form';
import { getAuthority, setAuthority } from '@/utils/authority';

interface tabDateInterface {
  key: string; // 菜单的 menuUrl 字段值
  menuName: string; // 菜单的 menuName 字段值
  menuId: string; // 菜单的 id 字段值
  params?: object | string; // 需要想对应tab传递的参数，对应tab页直接从props.params拿参数值
}

const { Option } = Select;

// 渲染菜单icon方法
const getIcon = (icon: string) => {
  if (typeof icon === 'string' && isUrl(icon)) {
    return <img src={icon} alt="icon" className='icon' style={{ marginRight: '10px' }}/>;
  }
  if (typeof icon === 'string') {
    return <span className={`menuIcon iconfont ${icon}`} style={{ marginRight: '10px' }}/>;
  }
  return icon;
};
// 系统主页面容器
const Index: React.FC = (props: {
  dispatch: Function;
}) => {
  const { dispatch } = props;
  const currentUser = getAuthority();

  // 系统名称
  const [sysName, setSysName] = useState<string>('伯乐寻骥管理系统');
  // 系统菜单
  const [menus, setMenus] = useState<any>([]);
  // main菜单右击操作菜单相关样式参数
  const [rightMenusKey, setRightMenusKey] = useState<string>('');
  const [rightMenusLeft, setRightMenusLeft] = useState<string>('');
  const [rightMenusTop, setRightMenusTop] = useState<string>('');
  const [rightMenusDisplay, setRightMenusDisplay] = useState<string>('none');
  // 当前组件，默认首页
  const [activeKey, setActiveKey] = useState<string>('homePage');
  // 组件对应的tab
  const [pageTabs, setPageTabs] = useState<any[]>([]);
  // 菜单折叠状态
  const [collapsed, setCollapsed] = useState<boolean>(false);

  const [orgTypeList, setOrgTypeList] = useState([{ id: '', name: '' }]);
  const [activeVisible, setActiveVisiable] = useState(currentUser?.active === 1);

  // 初始换展示的页面，首页
  const firstPageObj = {
    id: '001',
    key: 'homePage',
    title: '首页',
    component: HomePage,
    tabType: 1,
    closable: false,
  };

  useEffect(() => {
    // 初始化首页tab
    addPageTab(true, firstPageObj, firstPageObj.title, firstPageObj.id);

    // 获取用户菜单
    getLoginUserMenu();

    //单位层级
    listOrgType();

    // clear
    return () => {
    };
  }, []);

  useEffect(() => {

  }, [rightMenusKey]);

  // 获取用户菜单
  const getLoginUserMenu = () => {
    dispatch({
      type: 'sysUser/getLoginUserMenu',
      payload: {},
      callback: (e) => {
        if (e.code === 1) {
          let list = e.data || [];
          // 循环处理 menuUrl 全为空的时候，是一样的值，菜单异常的问题
          list.map((v: any, i: number) => {
            if (v.menuUrl === '' || v.menuUrl.trim() === '') {
              v.menuUrl = i;
            }
          });
          setMenus(list);
        } else {
          message.error(e.msg || '接口异常');
        }
      },
    });
  };

  // 给布局用的tab绑定右键事件
  const bindTabRightClick = (key: string) => {
    const tabs = document.querySelectorAll('.maxMainCom .mainTabsNav> .ant-tabs-nav > .ant-tabs-nav-wrap>.ant-tabs-nav-list>.ant-tabs-tab');
    if (tabs.length <= 1) return false;
    tabs[tabs.length - 1].addEventListener('contextmenu', onTabRightClick(key), false);
  };

  // 实际触发的右键事件
  const onTabRightClick = (key: string) => {
    return e => {
      e.preventDefault();
      window.zoom = window.zoom || 1;// 后面可能会添加zoom来控制用户界面缩放
      const left = `${e.clientX / window.zoom}px`;
      const top = `${e.clientY / window.zoom}px`;
      if (e.clientX) {
        setRightMenusKey(key);
        setRightMenusLeft(left);
        setRightMenusTop(top);
        setRightMenusDisplay('block');
      }
    };
  };

  // 鼠标离开右键菜单就关闭
  const onRightMenusMouseLeave = () => {
    setRightMenusKey('');
    setRightMenusLeft('');
    setRightMenusTop('');
    setRightMenusDisplay('none');
  };

  // 给右键菜单项绑定事件
  const onRightMenuItemClick = (e) => {
    const firstKey = firstPageObj.key; // tab默认第一页的key
    const clickType = e.target.getAttribute('data-clicktype');
    const tabIndex = pageTabs.findIndex(item => item.key === rightMenusKey);
    let returnTabs = [];
    let activeKey = rightMenusKey;

    if (tabIndex < 0) {
      return false;
    }
    switch (clickType) {
      case 'other': {
        returnTabs = pageTabs.filter(item => item.key === firstKey || item.key === rightMenusKey);
      }
        break;
      case 'left': {
        if (rightMenusKey === firstKey) {
          return false;
        }
        pageTabs.splice(1, tabIndex - 1);
        returnTabs = pageTabs;
      }
        break;
      case 'right': {
        pageTabs.splice(tabIndex + 1, pageTabs.length);
        returnTabs = pageTabs;
      }
        break;
      case 'all': {

        returnTabs = pageTabs.filter(item => item.key === firstKey);
        activeKey = firstKey;
      }
        break;
    }

    setPageTabs(returnTabs);
    setActiveKey(activeKey);
    setRightMenusDisplay('none');

  };

  // 改变tab选中项
  const onChangeTab = (activeKey: string) => {
    setActiveKey(activeKey);
  };


  // 输出左侧菜单去渲染
  const getRootMenus = (menus: any) => {
    if (!menus) {
      return [];
    }
    return menus.map((item: any) => getSubMenus(item));
  };

  const getSubMenus = (menu: any) => {
    if (menu.subMenu && menu.subMenu.length > 0) {
      return <SubMenu
        title={menu.icon ? <span>{getIcon(menu.icon)}<span>{menu.menuName}</span></span> : menu.menuName}
        key={menu.menuUrl}
      >
        {getRootMenus(menu.subMenu)}
      </SubMenu>;
    }

    return <Menu.Item
      key={menu.menuUrl}
      data-menuname={menu.menuName}
      data-menuid={menu.id}
      data-menu-url={menu.menuUrl}
      onClick={onClickMenu()}>
      <span>{getIcon(menu.icon)}<span>{menu.menuName}</span></span>
    </Menu.Item>;

  };

  // 点击菜单
  const onClickMenu = () => {
    return (menu: any): void => {
      // 如果是链接，则直接跳转
      if (menu.key && menu.key.indexOf('http') != -1) {
        window.open(menu.key);
        return;
      }
      // 现在现有的tabs里找下存不存在，存在就选中这个tab，不存在就载入并选中
      const menuName = menu.domEvent.currentTarget.getAttribute('data-menuName');
      const menuId = menu.domEvent.currentTarget.getAttribute('data-menuId');
      checkClickMenuAuth(menu, menuName, menuId);
    };
  };

  // 检测当前点击的菜单
  const checkClickMenuAuth = (menu: any, menuName: string, menuId: string) => {
    const findIndex = pageTabs.findIndex(item => item.key === menu.key);
    if (findIndex > -1) {
      // 如果已经打开过，只需要切到对应已打开的菜单处
      setActiveKey(menu.key);
    } else {
      if (pageTabs.length == 11) {
        // 打开的tab超过10个（排除首页）时不再添加新tab，并提示关闭之前的tab
        Modal.confirm({
          title: '提示',
          icon: <ExclamationCircleOutlined/>,
          content: `你打开的页面即将超过${pageTabs.length}个，为保证体验请先适当关闭后再继续，是否关闭现有所有页面。`,
          okText: '确认',
          cancelText: '取消',
          onOk: () => {
            setPageTabs(pageTabs.slice(0, 1));
            setActiveKey(firstPageObj.key);
          },
          onCancel: () => {
          },
        });
      } else {
        addPageTab(true, menu, menuName, menuId);
      }
    }
  };


  // 添加页面到tab
  const addPageTab = (authorized: boolean, menu: any, menuName: string, menuId: string) => {

    const tab: any = {
      title: menuName,
      key: menu.key,
      component: null,
      id: menuId,
      closable: menu.closable,
      params: menu.params || {},
    };

    if (authorized) {
      // 有权限
      import(`@/pages/${menu.key}/index.tsx`).then((e) => {
        // 组件存在
        tab.component = e.default;
        setPageTabs([...pageTabs, tab]);
        setActiveKey(tab.key);
        bindTabRightClick(menu.key);
      }).catch((e) => {
        // 组件不存在，去火星了
        tab.component = Error404;
        setPageTabs([...pageTabs, tab]);
        setActiveKey(tab.key);
        bindTabRightClick(menu.key);
      });

    } else {
      // 没有权限的403页面
      tab.component = Error403;
      setPageTabs([...pageTabs, tab]);
      setActiveKey(menu.key);
      bindTabRightClick(menu.key);
    }
  };

  /**
   * 加载tab页面
   */
  const loadPages = (pageTabs: any) => {
    if (pageTabs && pageTabs.length === 0) {
      return false;
    }
    return pageTabs.map((pane: any, i) => {
      return (
        <TabPane tab={pane.title} key={pane.key} closable={pane.closable}>
          <div className={`componentCom ${pane.key === 'homePage' ? 'componentComCover' : ''}`}>
            {
              pane.tabType === 1 ?
                pane.component :
                <pane.component
                  params={pane.params}
                  onCallBack={(type: string, value: tabDateInterface) => childComponentBack(type, value)}
                  key={pane.key}
                  pageKey={pane.key}
                  title={pane.title}/>
            }
          </div>
          <MyFooter name="©2021南京强基云计算科技有限公司出品"/>
        </TabPane>
      );
    });
  };

  /**
   * 删除一个tab
   */
  const onDeleteTab = (targetKey: string) => {
    const newTab = pageTabs.filter(v => v.key != targetKey);
    setPageTabs(newTab);
    if (targetKey === activeKey) {
      setActiveKey(newTab[newTab.length - 1].key);
    }
    if (newTab.length === 1) {
      newTab[0].closable = false;
    }
  };

  // 每个业务页面（组件）点击新增tab时，传回来的value值，可带参数
  const childComponentBack = (type: string, value: any) => {
    if (type === 'addTab') {
      // 如果是链接，则直接跳转
      if (value.key && value.key.indexOf('http') != -1) {
        window.open(value.key);
        return;
      }
      // 现在现有的tabs里找下存不存在，存在就选中这个tab，不存在就载入并选中
      const { menuName, menuId } = value;
      checkClickMenuAuth(value, menuName, menuId);
    }

  };

  const onCollapse = (collapsed: boolean) => setCollapsed(collapsed);

  const formItemLayout = {
    labelCol: { span: 7 },
    wrapperCol: { span: 14 },
  };

  /**
   * 套餐下拉列表
   */
  const listOrgType = () => {
    dispatch({
      type: 'register/listOrgType',
      payload: {
        typeCode: 'org_type_code',
      },
      callback: (response: any) => {
        if (response.code === 1) {
          setOrgTypeList(response.data);
        } else {
          message.error(response.msg);
        }
      },
    });
  };

  return <ConfigProvider locale={zhCN}>
    <div className='maxMainCom'>
      <Layout style={{ minHeight: '100vh' }}>
        <Sider collapsible collapsed={collapsed} onCollapse={onCollapse}>
          <div className="logo"/>
          <Menu theme="light" mode="inline" selectedKeys={[activeKey]} onClick={(e) => onClickMenu()}>
            <div className='sysTitleName'>
              <SysName collapsed={collapsed} name={sysName} onCallBack={setSysName}/>
            </div>
            {getRootMenus(menus)}
          </Menu>
        </Sider>
        <Layout className="site-layout">
          <Header className="site-layout-background" style={{ padding: 0 }}>
            <MyHeader/>
          </Header>
          <Content>
            {
              pageTabs.length &&
              <Tabs
                defaultActiveKey="home"
                className="mainTabsNav"
                onChange={onChangeTab}
                activeKey={activeKey}
                type="editable-card"
                tabBarGutter={0}
                hideAdd
                onEdit={onDeleteTab}
              >
                {loadPages(pageTabs)}
              </Tabs>
            }
          </Content>

          <div
            className="contextMenuItems"
            onMouseLeave={onRightMenusMouseLeave}
            style={{ left: rightMenusLeft, top: rightMenusTop, display: rightMenusDisplay }}
          >
            {
              [
                { clicktype: 'other', name: '关闭其他页面' },
                { clicktype: 'left', name: '关闭左侧页面' },
                { clicktype: 'right', name: '关闭右侧页面' },
                { clicktype: 'all', name: '关闭所有页面' },
              ].map((v) => <div className="menuItem" onClick={onRightMenuItemClick}
                                data-clicktype={v.clicktype}>{v.name}</div>)
            }

          </div>
        </Layout>
      </Layout>

      <ModalForm
        title="单位入驻"
        visible={activeVisible}
        {...formItemLayout}
        layout="horizontal"
        submitter={{
          resetButtonProps: {
            style: {
              display: 'none',
            },
          },
        }}
        modalProps={{
          closable: false,
        }}
        onFinish={async (values: any) => {
          dispatch({
            type: 'register/orgActive',
            payload: values,
            callback: (res: any) => {
              if (res.code === 1) {
                message.success(res.msg || '入驻成功！');

                currentUser.active = 0;
                currentUser.maxOrg.shortName = values.orgShortName
                setAuthority(currentUser);
                setActiveVisiable(false);
              } else {
                message.error(res.msg);

                currentUser.active = 0;
                currentUser.maxOrg.shortName = values.orgShortName
                setAuthority(currentUser);
                setActiveVisiable(false);
              }
            },
          });
        }}
      >
        <ProFormText name="saleMeal" label="套餐" readonly initialValue={currentUser?.saleMeal}/>
        <ProFormText name="orgName" label="入驻单位全称" required initialValue={currentUser?.sysOrgName}/>
        <ProFormText name="orgShortName" label="入驻单位简称" required initialValue={currentUser?.sysOrgName}/>

        <Form.Item name="typeId" label="单位层级" required>
          <Select placeholder="请选择套餐类型">
            {
              orgTypeList.map(value => (
                <Option value={value.id}>{value.name}</Option>),
              )
            }
          </Select>
        </Form.Item>

      </ModalForm>
    </div>
  </ConfigProvider>;
};

export default connect(
  ({ home, sysUser, loading }: { home: any; sysUser: any; loading: boolean }) => ({
    home,
    sysUser,
    loading: loading.models.user,
  }),
)(Index);
